
import javax.swing.*;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import java.awt.*;
import java.awt.event.*;
import calendar_ex.*;
import java.util.*;

public class MonthViewPanel extends ObservingJPanel {

    CalendarEx calendarModel;
    JScrollPane ePane;
    JButton[] buttons;
    JList eventJList;
    ArrayList<Appointment> appList;

    public MonthViewPanel(CalendarEx model, CalendarController controller) {
        super(model, controller);
        this.calendarModel = model;
        this.update();
    }

    public void update() {
        this.removeAll();
        GregorianCalendar firstDay = new GregorianCalendar(calendarModel.getViewDate().getYear(), calendarModel.getViewDate().getMonth() - 1, 1);
        Calendar today = Calendar.getInstance();
        buttons = new JButton[31];
        int month = calendarModel.getViewDate().getMonth();
        int year = calendarModel.getViewDate().getYear();

        int day_count = 0;
        switch (month) {
            case 1:
                day_count = 31;
                break;
            case 2:
                day_count = 28;
                break;
            case 3:
                day_count = 31;
                break;
            case 4:
                day_count = 30;
                break;
            case 5:
                day_count = 31;
                break;
            case 6:
                day_count = 30;
                break;
            case 7:
                day_count = 31;
                break;
            case 8:
                day_count = 31;
                break;
            case 9:
                day_count = 30;
                break;
            case 10:
                day_count = 31;
                break;
            case 11:
                day_count = 30;
                break;
            case 12:
                day_count = 31;
                break;
            default:
                day_count = 31;
                break;
        }
        if (day_count == 28 && (((year % 4) == 0 && (year % 100) != 0) || (year % 400) == 0)) {
            day_count++;
        }
        System.out.println("hotspot mode: " + calendarModel.getHotSpot());
        int eventCount = 0;
        int[] eventCounters = new int[31];
        
            for (int i = 0; i < day_count; i++) {
                CalendarDate curd = new CalendarDate(i + 1, month, year);
                eventCount += calendarModel.getAppointmentsBetweenDates(curd, curd).size();
                eventCounters[i] += calendarModel.getAppointmentsBetweenDates(curd, curd).size();
            }
        
        JPanel grid = new JPanel();
        grid.setBackground(Color.WHITE);
        grid.setPreferredSize(new Dimension(300, 300));
        grid.setLayout(new GridLayout(0, 7));

        grid.add(new JLabel("M", SwingConstants.CENTER));
        grid.add(new JLabel("T", SwingConstants.CENTER));
        grid.add(new JLabel("W", SwingConstants.CENTER));
        grid.add(new JLabel("T", SwingConstants.CENTER));
        grid.add(new JLabel("F", SwingConstants.CENTER));
        grid.add(new JLabel("S", SwingConstants.CENTER));
        grid.add(new JLabel("S", SwingConstants.CENTER));
        int startPadding = Math.abs(GregorianCalendar.MONDAY - firstDay.get(GregorianCalendar.DAY_OF_WEEK));
        int start;
        switch (month - 1) {
            case 1:
                start = 31;
                break;
            case 2:
                start = 28;
                break;
            case 3:
                start = 31;
                break;
            case 4:
                start = 30;
                break;
            case 5:
                start = 31;
                break;
            case 6:
                start = 30;
                break;
            case 7:
                start = 31;
                break;
            case 8:
                start = 31;
                break;
            case 9:
                start = 30;
                break;
            case 10:
                start = 31;
                break;
            case 11:
                start = 30;
                break;
            case 12:
                start = 31;
                break;
            default:
                start = 31;
                break;
        }
        if (start == 28 && (((year % 4) == 0 && (year % 100) != 0) || (year % 400) == 0)) {
            start++;
        }
        for (int i = 0; i < startPadding; i++) {
            grid.add(new JLabel());
        }
        for (int i = 1; i < day_count + 1; i++) {
            if (eventCounters[i - 1] != 0) {
                
                buttons[i - 1] = new JButton(Integer.toString(i) + "\n.");

            } else {
                
                buttons[i - 1] = new JButton(Integer.toString(i));
            }

            buttons[i - 1].setMargin(new Insets(0, 0, 0, 0));
            buttons[i - 1].addActionListener(new MonthViewDayListener(i, month, year));

            if (calendarModel.getHotSpot()) {
                if (eventCounters[i - 1] == 0) {
                    buttons[i - 1].setBackground(new Color(0, 0, 170));
                } else {
                    buttons[i - 1].setBackground(new Color((int) ((255 / (eventCounters[i - 1])) * 0.75), 0, 0));

                }
                buttons[i - 1].setOpaque(true);

            } else {
                buttons[i - 1].setBackground(Color.WHITE);
                buttons[i - 1].setOpaque(true);


                if (calendarModel.getViewDate().getYear() == today.get(Calendar.YEAR) && calendarModel.getViewDate().getMonth() == today.get(Calendar.MONTH) + 1 && i == today.get(Calendar.DAY_OF_MONTH)) {
                    buttons[i - 1].setBackground(new Color(46, 139, 87));
                    buttons[i - 1].setOpaque(true);
                }
            }
            grid.add(buttons[i - 1]);
        }
        ArrayList<String> eventList = new ArrayList<String>();
        appList = new ArrayList<Appointment>();
        CalendarDate startDate = new CalendarDate(calendarModel.getViewDate().getDay(), calendarModel.getViewDate().getMonth(), calendarModel.getViewDate().getYear());
        for (Appointment app : calendarModel.getAppointmentsBetweenDates(startDate, startDate)) {
            if (app.name == "" || app.name == null) {
                eventList.add(app.description);
            } else {
                eventList.add(app.name);
            }
            appList.add(app);
        }
        this.add(grid);
        eventJList = new JList(eventList.toArray());
        eventJList.addListSelectionListener(new ListSelectionListener() {

            public void valueChanged(ListSelectionEvent le) {
                int idx = eventJList.getSelectedIndex();
                if (idx != -1) {
                    System.out.println("Currdaadadent selection: " + appList.get(idx));
                    calendarModel.setCurrentAppointment(appList.get(idx));
                    calendarController.changeView(IS3Calendar.View.EVENT);
                } else {
                    System.out.println("Please choose a language.");
                }
            }
        });
        ePane = new JScrollPane(eventJList);
        ePane.setBackground(Color.LIGHT_GRAY);
        ePane.setPreferredSize(new Dimension(290, 90));
        this.add(ePane);
    }

    class MonthViewDayListener implements ActionListener {

        int d;
        int m;
        int y;

        public MonthViewDayListener(int d, int m, int y) {
            this.d = d;
            this.m = m;
            this.y = y;
        }

        @Override
        public void actionPerformed(ActionEvent e) {
            Calendar today = Calendar.getInstance();
            System.out.println(calendarModel.getViewDate().getDay());
            System.out.println(calendarModel.getViewDate().getMonth());
            System.out.println(calendarModel.getViewDate().getYear());
            if (!calendarModel.getHotSpot()) {

                if (!(calendarModel.getViewDate().getDay() == today.get(Calendar.DAY_OF_MONTH) && calendarModel.getViewDate().getMonth() == today.get(Calendar.MONTH) + 1 && calendarModel.getViewDate().getYear() == today.get(Calendar.YEAR))) {
                    buttons[calendarModel.getViewDate().getDay() - 1].setBackground(Color.WHITE);
                } else {
                    buttons[calendarModel.getViewDate().getDay() - 1].setBackground(new Color(46, 139, 87));
                }
            }
            calendarModel.setViewDate(new CalendarDate(d, m, y));
            CalendarDate pressedDate = new CalendarDate(d, m, y);
            ArrayList<String> eventList = new ArrayList<String>();
            appList.clear();
            for (Appointment app : calendarModel.getAppointmentsBetweenDates(pressedDate, pressedDate)) {
                if (app.name == "" || app.name == null) {
                    eventList.add(app.description);
                } else {
                    eventList.add(app.name);
                }
                appList.add(app);
            }
            if (!calendarModel.getHotSpot()) {
                buttons[d - 1].setBackground(new Color(173, 255, 47));
                buttons[d - 1].setOpaque(true);
            }
            remove(ePane);
            repaint();
            eventJList = new JList(eventList.toArray());
            eventJList.addListSelectionListener(new ListSelectionListener() {

                public void valueChanged(ListSelectionEvent le) {
                    int idx = eventJList.getSelectedIndex();

                    if (idx != -1) {
                        System.out.println("2Current selection: " + appList.get(idx));
                        calendarModel.setCurrentAppointment(appList.get(idx));
                        calendarController.changeView(IS3Calendar.View.EVENT);
                    } else {
                        System.out.println("Please choose a language.");
                    }
                }
            });
            ePane = new JScrollPane(eventJList);
            ePane.setPreferredSize(new Dimension(290, 90));
            add(ePane);
            revalidate();
            repaint();
        }
    }
}
